﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Office.Interop.Excel;

namespace Lottery.MediaData.Core {
    public class HZText {
        public string Three { get; set; }
        public string One { get; set; }
        public string Zero { get; set; }

        public decimal GetValue(long ln) {
            switch (ln) {
                case 4L:
                    return m_threeValue;
                case 2L:
                    return m_oneValue;
                case 1L:
                    return m_zeroValue;
                default:
                    return 0;
            }
        }

        private decimal m_threeValue;
        private decimal m_oneValue;
        private decimal m_zeroValue;

        public void SetupValues() {
            try {
                m_threeValue = Convert.ToDecimal(Three);
            } catch {
                m_threeValue = 0;
            }

            try {
                m_oneValue = Convert.ToDecimal(One);
            } catch {
                m_oneValue = 0;
            }
            try {
                m_zeroValue = Convert.ToDecimal(Zero);
            } catch {
                m_zeroValue = 0;
            }
        }
    }

    public class HZLine {
        public HZLine() {
            m_hz = new List<HZText>();
            for (int i = 0; i < 14; i++) {
                m_hz.Add(new HZText());
            }
        }

        private List<HZText> m_hz;

        /// <summary>
        /// 限制下限
        /// </summary>
        public string A { get; set; }

        /// <summary>
        /// 限制上限
        /// </summary>
        public string B { get; set; }

        /// <summary>
        /// 序号
        /// </summary>
        public string Index { get; set; }

        public HZText this[int index] { get { return m_hz[index]; } }
    }

    /// <summary>
    /// 和值 助手类
    /// </summary>
    public static class HZHelper {
        public static List<HZLine> LoadFromExcel(string fileName) {
            var result = new List<HZLine>();

            var app = new ApplicationClass();
            app.Visible = false;

            app.Workbooks.Open(fileName, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            Worksheet ws = app.ActiveWorkbook.ActiveSheet as Worksheet;
            var row = 3;
            var rowOffset = 0;
            while (true) {
                var cell = ws.Cells[row, 1] as Range;
                if (string.IsNullOrEmpty(cell.Text.ToString())) {
                    break;
                } else {
                    rowOffset++;
                }

                row++;
            }

            var COL_COUNT = 3 + 14 * 3;
            if (rowOffset > 1) {
                var r = ws.get_Range(ws.Cells[3, 1], ws.Cells[2 + rowOffset, COL_COUNT]);
                var d = r.Value2 as object[,];

                var rowCount = d.Length / COL_COUNT;
                for (int iRow = 1; iRow <= rowCount; iRow++) {
                    var line = new HZLine();
                    line.Index = d[iRow, 1] == null ? string.Empty : d[iRow, 1].ToString();
                    line.A = d[iRow, 2] == null ? string.Empty : d[iRow, 2].ToString();
                    line.B = d[iRow, 3] == null ? string.Empty : d[iRow, 3].ToString();
                    for (int i = 0; i < 14; i++) {
                        var hz = line[i];
                        var idx = 4 + i * 3;
                        hz.Three = d[iRow, idx] != null ? d[iRow, idx].ToString() : string.Empty;
                        hz.One = d[iRow, idx + 1] != null ? d[iRow, idx + 1].ToString() : string.Empty;
                        hz.Zero = d[iRow, idx + 2] != null ? d[iRow, idx + 2].ToString() : string.Empty;
                    }
                    result.Add(line);
                }
            } else if (rowOffset == 1) {
                /* 
                 * 当rowOffset为1的时候
                 * var r = ws.get_Range(ws.Cells[3, 1], ws.Cells[2 + rowOffset, COL_COUNT]);
                 * var d = r.Value2 as object[,];
                 * 这段代码中d会等于null
                 * 所以才采用下面特别的写法。
                 */
                var line = new HZLine();
                line.Index = (ws.Cells[3, 1] as Range).Text.ToString();
                line.A = (ws.Cells[3, 2] as Range).Text.ToString();
                line.B = (ws.Cells[3, 3] as Range).Text.ToString();
                for (int i = 0; i < 14; i++) {
                    var hz = line[i];
                    var idx = 4 + i * 3;
                    hz.Three = (ws.Cells[3, idx] as Range).Text.ToString();
                    hz.One = (ws.Cells[3, idx + 1] as Range).Text.ToString();
                    hz.Zero = (ws.Cells[3, idx + 2] as Range).Text.ToString();
                }
                result.Add(line);
            }

            app.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
            app = null;

            return result;
        }

        public static List<long> DoFilter(List<HZLine> data, List<long> touZhu) {
            var touZhuStutas = new List<bool>();
            for (int i = 0; i < touZhu.Count; i++) {
                touZhuStutas.Add(true);
            }

            foreach (var item in data) {
                for (int i = 0; i < 14; i++) {
                    item[i].SetupValues();
                }
            }

            foreach (var hzLine in data) {
                var a = Convert.ToDecimal(hzLine.A);
                var b = Convert.ToDecimal(hzLine.B);

                for (int i = 0; i < touZhuStutas.Count; i++) {
                    if (!touZhuStutas[i]) continue;

                    decimal sum = 0;
                    for (int order = 0; order < 14; order++) {
                        var hz = hzLine[order];
                        var item = touZhu[i];
                        var ln = (item & (7L << (13 - order) * 3)) >> (13 - order) * 3;
                        sum += hz.GetValue(ln);
                    }

                    touZhuStutas[i] = sum >= a && sum <= b;
                }
            }

            var result = new List<long>();
            for (int i = 0; i < touZhuStutas.Count; i++) {
                if (touZhuStutas[i]) result.Add(touZhu[i]);
            }

            return result;
        }
    }
}
